home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr57 / mentc.zip / WINDOW.C < prev    next >
C/C++ Source or Header  |  1993-06-01  |  21KB  |  904 lines

  1. /*
  2.  * Window management. Some of the functions are internal, and some are
  3.  * attached to keys that the user actually types.
  4.  */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "eproto.h"
  9. #include    "edef.h"
  10. #include    "elang.h"
  11.  
  12. /*
  13.  * Reposition dot in the current window to line "n". If the argument is
  14.  * positive, it is that line. If it is negative it is that line from the
  15.  * bottom. If it is 0 the window is centered (this is what the standard
  16.  * redisplay code does). With no argument it defaults to 0. Bound to M-!.
  17.  */
  18. PASCAL NEAR reposition(f, n)
  19.  
  20. int f, n;    /* prefix flag and argument */
  21.  
  22. {
  23.     if (f == FALSE)    /* default to 0 to center screen */
  24.     n = 0;
  25.     curwp->w_force = n;
  26.     curwp->w_flag |= WFFORCE;
  27.     return (TRUE);
  28.     }
  29.  
  30. /*
  31.  * Refresh the screen. With no argument, it just does the refresh. With an
  32.  * argument it recenters "." in the current window. Bound to "C-L".
  33.  */
  34. PASCAL NEAR refresh(f, n)
  35.  
  36. int f, n;    /* prefix flag and argument */
  37.  
  38. {
  39.     if (f == FALSE)
  40.     sgarbf = TRUE;
  41.     else
  42.     {
  43.     curwp->w_force = 0;        /* Center dot. */
  44.     curwp->w_flag |= WFFORCE;
  45.     }
  46.  
  47.     return (TRUE);
  48.     }
  49.  
  50. /*
  51.  * The command make the next window (next => down the screen) the current
  52.  * window. There are no real errors, although the command does nothing if
  53.  * there is only 1 window on the screen. Bound to "C-X C-N".
  54.  *
  55.  * with an argument this command finds the <n>th window from the top
  56.  *
  57.  */
  58. PASCAL NEAR nextwind(f, n)
  59.  
  60. int f, n;    /* default flag and numeric argument */
  61.  
  62. {
  63.     register WINDOW *wp;
  64.     register int nwindows;        /* total number of windows */
  65.  
  66.     if (f) {
  67.  
  68.         /* first count the # of windows */
  69.         wp = wheadp;
  70.         nwindows = 1;
  71.         while (wp->w_wndp != NULL) {
  72.             nwindows++;
  73.             wp = wp->w_wndp;
  74.         }
  75.  
  76.         /* if the argument is negative, it is the nth window
  77.            from the bottom of the screen            */
  78.         if (n < 0)
  79.             n = nwindows + n + 1;
  80.  
  81.         /* if an argument, give them that window from the top */
  82.         if (n > 0 && n <= nwindows) {
  83.             wp = wheadp;
  84.             while (--n)
  85.                 wp = wp->w_wndp;
  86.         } else {
  87.             mlwrite(TEXT203);
  88. /*                "Window number out of range" */
  89.             return(FALSE);
  90.         }
  91.     } else
  92.         if ((wp = curwp->w_wndp) == NULL)
  93.             wp = wheadp;
  94.     curwp = wp;
  95.     curbp = wp->w_bufp;
  96.     upmode();
  97.     return (TRUE);
  98. }
  99.  
  100. /*
  101.  * This command makes the previous window (previous => up the screen) the
  102.  * current window. There arn't any errors, although the command does not do a
  103.  * lot if there is 1 window.
  104.  */
  105. PASCAL NEAR prevwind(f, n)
  106.  
  107. int f,n;    /* prefix flag and argument */
  108.  
  109. {
  110.     register WINDOW *wp1;
  111.     register WINDOW *wp2;
  112.  
  113.     /* if we have an argument, we mean the nth window from the bottom */
  114.     if (f)
  115.         return(nextwind(f, -n));
  116.  
  117.     wp1 = wheadp;
  118.     wp2 = curwp;
  119.  
  120.     if (wp1 == wp2)
  121.         wp2 = NULL;
  122.  
  123.     while (wp1->w_wndp != wp2)
  124.         wp1 = wp1->w_wndp;
  125.  
  126.     curwp = wp1;
  127.     curbp = wp1->w_bufp;
  128.     upmode();
  129.     return (TRUE);
  130. }
  131.  
  132. /*
  133.  * This command moves the current window down by "arg" lines. Recompute the
  134.  * top line in the window. The move up and move down code is almost completely
  135.  * the same; most of the work has to do with reframing the window, and picking
  136.  * a new dot. We share the code by having "move down" just be an interface to
  137.  * "move up". Magic. Bound to "C-X C-N".
  138.  */
  139. PASCAL NEAR mvdnwind(f, n)
  140.  
  141. int f, n;    /* prefix flag and argument */
  142.  
  143. {
  144.     return (mvupwind(f, -n));
  145. }
  146.  
  147. /*
  148.  * Move the current window up by "arg" lines. Recompute the new top line of
  149.  * the window. Look to see if "." is still on the screen. If it is, you win.
  150.  * If it isn't, then move "." to center it in the new framing of the window
  151.  * (this command does not really move "."; it moves the frame). Bound to
  152.  * "C-X C-P".
  153.  */
  154. PASCAL NEAR mvupwind(f, n)
  155.  
  156. int f, n;    /* prefix flag and argument */
  157.  
  158. {
  159.     register LINE *lp;
  160.     register int i;
  161.  
  162.     lp = curwp->w_linep;
  163.  
  164.     if (n < 0)
  165.     {
  166.     while (n++ && lp!=curbp->b_linep)
  167.         lp = lforw(lp);
  168.     }
  169.     else
  170.     {
  171.     while (n-- && lback(lp)!=curbp->b_linep)
  172.         lp = lback(lp);
  173.     }
  174.  
  175.     curwp->w_linep = lp;
  176.     curwp->w_flag |= WFHARD;        /* Mode line is OK. */
  177.  
  178.     for (i = 0; i < curwp->w_ntrows; ++i)
  179.     {
  180.     if (lp == curwp->w_dotp)
  181.         return (TRUE);
  182.     if (lp == curbp->b_linep)
  183.         break;
  184.     lp = lforw(lp);
  185.     }
  186.  
  187.     lp = curwp->w_linep;
  188.     i  = curwp->w_ntrows/2;
  189.  
  190.     while (i-- && lp != curbp->b_linep)
  191.     lp = lforw(lp);
  192.  
  193.     curwp->w_dotp  = lp;
  194.     curwp->w_doto  = 0;
  195.     return (TRUE);
  196.     }
  197.  
  198. /*
  199.  * This command makes the current window the only window on the screen. Bound
  200.  * to "C-X 1". Try to set the framing so that "." does not have to move on the
  201.  * display. Some care has to be taken to keep the values of dot and mark in
  202.  * the buffer structures right if the distruction of a window makes a buffer
  203.  * become undisplayed.
  204.  */
  205. PASCAL NEAR onlywind(f, n)
  206.  
  207. int f,n;    /* prefix flag and argument */
  208.  
  209. {
  210.     register WINDOW *wp;
  211.     register LINE    *lp;
  212.     register int    i;
  213.     int cmark;        /* current mark */
  214.  
  215.     while (wheadp != curwp) {
  216.         wp = wheadp;
  217.         first_screen->s_first_window = wheadp = wp->w_wndp;
  218.         if (--wp->w_bufp->b_nwnd == 0) {
  219.             wp->w_bufp->b_dotp  = wp->w_dotp;
  220.             wp->w_bufp->b_doto  = wp->w_doto;
  221.             for (cmark = 0; cmark < NMARKS; cmark++) {
  222.                 wp->w_bufp->b_markp[cmark] = wp->w_markp[cmark];
  223.                 wp->w_bufp->b_marko[cmark] = wp->w_marko[cmark];
  224.             }
  225.             wp->w_bufp->b_fcol  = wp->w_fcol;
  226.         }
  227.         free((char *) wp);
  228.     }
  229.     while (curwp->w_wndp != NULL) {
  230.         wp = curwp->w_wndp;
  231.         curwp->w_wndp = wp->w_wndp;
  232.         if (--wp->w_bufp->b_nwnd == 0) {
  233.             wp->w_bufp->b_dotp  = wp->w_dotp;
  234.             wp->w_bufp->b_doto  = wp->w_doto;
  235.             for (cmark = 0; cmark < NMARKS; cmark++) {
  236.                 wp->w_bufp->b_markp[cmark] = wp->w_markp[cmark];
  237.                 wp->w_bufp->b_marko[cmark] = wp->w_marko[cmark];
  238.             }
  239.             wp->w_bufp->b_fcol  = wp->w_fcol;
  240.         }
  241.         free((char *) wp);
  242.     }
  243.     lp = curwp->w_linep;
  244.     i  = curwp->w_toprow;
  245.     while (i!=0 && lback(lp)!=curbp->b_linep) {
  246.         --i;
  247.         lp = lback(lp);
  248.     }
  249.     curwp->w_toprow = 0;
  250.     curwp->w_ntrows = term.t_nrow-1;
  251.     curwp->w_linep    = lp;
  252.     curwp->w_flag  |= WFMODE|WFHARD;
  253.     return (TRUE);
  254. }
  255.  
  256. /*
  257.  * Delete the current window, placing its space in the window above,
  258.  * or, if it is the top window, the window below. Bound to C-X 0.
  259.  */
  260.  
  261. PASCAL NEAR delwind(f,n)
  262.  
  263. int f, n;    /* arguments are ignored for this command */
  264.  
  265. {
  266.     register WINDOW *wp;    /* window to recieve deleted space */
  267.     register WINDOW *lwp;    /* ptr window before curwp */
  268.     register int target;    /* target line to search for */
  269.     int cmark;        /* current mark */
  270.  
  271.     /* if there is only one window, don't delete it */
  272.     if (wheadp->w_wndp == NULL) {
  273.         mlwrite(TEXT204);
  274. /*            "Can not delete this window" */
  275.         return(FALSE);
  276.     }
  277.  
  278.     /* find window before curwp in linked list */
  279.     wp = wheadp;
  280.     lwp = NULL;
  281.     while (wp != NULL) {
  282.         if (wp == curwp)
  283.             break;
  284.         lwp = wp;
  285.         wp = wp->w_wndp;
  286.     }
  287.  
  288.     /* find recieving window and give up our space */
  289.     wp = wheadp;
  290.     if (curwp->w_toprow == 0) {
  291.         /* find the next window down */
  292.         target = curwp->w_ntrows + 1;
  293.         while (wp != NULL) {
  294.             if (wp->w_toprow == target)
  295.                 break;
  296.             wp = wp->w_wndp;
  297.         }
  298.         if (wp == NULL)
  299.             return(FALSE);
  300.         wp->w_toprow = 0;
  301.         wp->w_ntrows += target;
  302.     } else {
  303.         /* find the next window up */
  304.         target = curwp->w_toprow - 1;
  305.         while (wp != NULL) {
  306.             if ((wp->w_toprow + wp->w_ntrows) == target)
  307.                 break;
  308.             wp = wp->w_wndp;
  309.         }
  310.         if (wp == NULL)
  311.             return(FALSE);
  312.         wp->w_ntrows += 1 + curwp->w_ntrows;
  313.     }
  314.  
  315.     /* get rid of the current window */
  316.     if (--curwp->w_bufp->b_nwnd == 0) {
  317.         curwp->w_bufp->b_dotp  = curwp->w_dotp;
  318.         curwp->w_bufp->b_doto  = curwp->w_doto;
  319.         for (cmark = 0; cmark < NMARKS; cmark++) {
  320.             curwp->w_bufp->b_markp[cmark] = curwp->w_markp[cmark];
  321.             curwp->w_bufp->b_marko[cmark] = curwp->w_marko[cmark];
  322.         }
  323.         curwp->w_bufp->b_fcol  = curwp->w_fcol;
  324.     }
  325.     if (lwp == NULL)
  326.         first_screen->s_first_window = wheadp = curwp->w_wndp;
  327.     else
  328.         lwp->w_wndp = curwp->w_wndp;
  329.     free((char *)curwp);
  330.     curwp = wp;
  331.     wp->w_flag |= WFHARD;
  332.     curbp = wp->w_bufp;
  333.     upmode();
  334.     return(TRUE);
  335. }
  336.  
  337. /*
  338.  
  339. Split the current window.  A window smaller than 3 lines cannot be
  340. split.    (Two line windows can be split when mode lines are disabled) An
  341. argument of 1 forces the cursor into the upper window, an argument of
  342. two forces the cursor to the lower window.  The only other error that
  343. is possible is a "malloc" failure allocating the structure for the new
  344. window.  Bound to "C-X 2". 
  345.  
  346. */
  347.  
  348. PASCAL NEAR splitwind(f, n)
  349.  
  350. int f, n;    /* default flag and numeric argument */
  351.  
  352. {
  353.     register WINDOW *wp;
  354.     register LINE    *lp;
  355.     register int    ntru;
  356.     register int    ntrl;
  357.     register int    ntrd;
  358.     register WINDOW *wp1;
  359.     register WINDOW *wp2;
  360.     int cmark;        /* current mark */
  361.  
  362.     /* make sure we have enough space */
  363.     if (curwp->w_ntrows < (modeflag ? 3 : 2)) {
  364.         mlwrite(TEXT205, curwp->w_ntrows);
  365. /*            "Cannot split a %d line window" */
  366.         return (FALSE);
  367.     }
  368.     if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
  369.         mlwrite(TEXT94);
  370. /*            "%%Out of memory" */
  371.         return (FALSE);
  372.     }
  373.     ++curbp->b_nwnd;            /* Displayed twice.    */
  374.     wp->w_bufp  = curbp;
  375.     wp->w_dotp  = curwp->w_dotp;
  376.     wp->w_doto  = curwp->w_doto;
  377.     for (cmark = 0; cmark < NMARKS; cmark++) {
  378.         wp->w_markp[cmark] = curwp->w_markp[cmark];
  379.         wp->w_marko[cmark] = curwp->w_marko[cmark];
  380.     }
  381.     wp->w_fcol  = curwp->w_fcol;
  382.     wp->w_flag  = 0;
  383.     wp->w_force = 0;
  384. #if    COLOR
  385.     /* set the colors of the new window */
  386.     wp->w_fcolor = gfcolor;
  387.     wp->w_bcolor = gbcolor;
  388. #endif
  389.     ntru = (curwp->w_ntrows-1) / 2;     /* Upper size        */
  390.     ntrl = (curwp->w_ntrows-1) - ntru;    /* Lower size        */
  391.     lp = curwp->w_linep;
  392.     ntrd = 0;
  393.     while (lp != curwp->w_dotp) {
  394.         ++ntrd;
  395.         lp = lforw(lp);
  396.     }
  397.     lp = curwp->w_linep;
  398.     if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) {
  399.         /* Old is upper window. */
  400.         if (ntrd == ntru)        /* Hit mode line.    */
  401.             lp = lforw(lp);
  402.         curwp->w_ntrows = ntru;
  403.         wp->w_wndp = curwp->w_wndp;
  404.         curwp->w_wndp = wp;
  405.         wp->w_toprow = curwp->w_toprow+ntru+1;
  406.         wp->w_ntrows = ntrl;
  407.     } else {                /* Old is lower window    */
  408.         wp1 = NULL;
  409.         wp2 = wheadp;
  410.         while (wp2 != curwp) {
  411.             wp1 = wp2;
  412.             wp2 = wp2->w_wndp;
  413.         }
  414.         if (wp1 == NULL)
  415.             first_screen->s_first_window = wheadp = wp;
  416.         else
  417.             wp1->w_wndp = wp;
  418.         wp->w_wndp   = curwp;
  419.         wp->w_toprow = curwp->w_toprow;
  420.         wp->w_ntrows = ntru;
  421.         ++ntru;             /* Mode line.        */
  422.         curwp->w_toprow += ntru;
  423.         curwp->w_ntrows  = ntrl;
  424.         while (ntru--)
  425.             lp = lforw(lp);
  426.     }
  427.     curwp->w_linep = lp;            /* Adjust the top lines */
  428.     wp->w_linep = lp;            /* if necessary.    */
  429.     curwp->w_flag |= WFMODE|WFHARD;
  430.     wp->w_flag |= WFMODE|WFHARD;
  431.     return (TRUE);
  432. }
  433.  
  434. /*
  435.  * Enlarge the current window. Find the window that loses space. Make sure it
  436.  * is big enough. If so, hack the window descriptions, and ask redisplay to do
  437.  * all the hard work. You don't just set "force reframe" because dot would
  438.  * move. Bound to "C-X Z".
  439.  */
  440. PASCAL NEAR enlargewind(f, n)
  441.  
  442. int f,n;    /* prefix flag and argument */
  443.  
  444. {
  445.     register WINDOW *adjwp;
  446.     register LINE    *lp;
  447.     register int    i;
  448.  
  449.     if (n < 0)
  450.         return (shrinkwind(f, -n));
  451.     if (wheadp->w_wndp == NULL) {
  452.         mlwrite(TEXT206);
  453. /*            "Only one window" */
  454.         return (FALSE);
  455.     }
  456.     if ((adjwp=curwp->w_wndp) == NULL) {
  457.         adjwp = wheadp;
  458.         while (adjwp->w_wndp != curwp)
  459.             adjwp = adjwp->w_wndp;
  460.     }
  461.     if ((adjwp->w_ntrows + (modeflag ? 0 : 1)) <= n) {
  462.         mlwrite(TEXT207);
  463. /*            "Impossible change" */
  464.         return (FALSE);
  465.     }
  466.     if (curwp->w_wndp == adjwp) {        /* Shrink below.    */
  467.         lp = adjwp->w_linep;
  468.         for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
  469.             lp = lforw(lp);
  470.         adjwp->w_linep    = lp;
  471.         adjwp->w_toprow += n;
  472.     } else {                /* Shrink above.    */
  473.         lp = curwp->w_linep;
  474.         for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
  475.             lp = lback(lp);
  476.         curwp->w_linep    = lp;
  477.         curwp->w_toprow -= n;
  478.     }
  479.     curwp->w_ntrows += n;
  480.     adjwp->w_ntrows -= n;
  481.     curwp->w_flag |= WFMODE|WFHARD;
  482.     adjwp->w_flag |= WFMODE|WFHARD;
  483.     return (TRUE);
  484. }
  485.  
  486. /*
  487.  * Shrink the current window. Find the window that gains space. Hack at the
  488.  * window descriptions. Ask the redisplay to do all the hard work. Bound to
  489.  * "C-X C-Z".
  490.  */
  491. PASCAL NEAR shrinkwind(f, n)
  492.  
  493. int f,n;    /* prefix flag and argument */
  494.  
  495. {
  496.     register WINDOW *adjwp;
  497.     register LINE    *lp;
  498.     register int    i;
  499.  
  500.     if (n < 0)
  501.         return (enlargewind(f, -n));
  502.     if (wheadp->w_wndp == NULL) {
  503.         mlwrite(TEXT206);
  504. /*            "Only one window" */
  505.         return (FALSE);
  506.     }
  507.     if ((adjwp=curwp->w_wndp) == NULL) {
  508.         adjwp = wheadp;
  509.         while (adjwp->w_wndp != curwp)
  510.             adjwp = adjwp->w_wndp;
  511.     }
  512.     if ((curwp->w_ntrows + (modeflag ? 0 : 1)) <= n) {
  513.         mlwrite(TEXT207);
  514. /*            "Impossible change" */
  515.         return (FALSE);
  516.     }
  517.     if (curwp->w_wndp == adjwp) {        /* Grow below.        */
  518.         lp = adjwp->w_linep;
  519.         for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
  520.             lp = lback(lp);
  521.         adjwp->w_linep    = lp;
  522.         adjwp->w_toprow -= n;
  523.     } else {                /* Grow above.        */
  524.         lp = curwp->w_linep;
  525.         for (i=0; i<n && lp!=curbp->b_linep; ++i)
  526.             lp = lforw(lp);
  527.         curwp->w_linep    = lp;
  528.         curwp->w_toprow += n;
  529.     }
  530.     curwp->w_ntrows -= n;
  531.     adjwp->w_ntrows += n;
  532.     curwp->w_flag |= WFMODE|WFHARD;
  533.     adjwp->w_flag |= WFMODE|WFHARD;
  534.     return (TRUE);
  535. }
  536.  
  537. /*    Resize the current window to the requested size */
  538.  
  539. PASCAL NEAR resize(f, n)
  540.  
  541. int f, n;    /* default flag and numeric argument */
  542.  
  543. {
  544.     int clines;    /* current # of lines in window */
  545.         
  546.     /* must have a non-default argument, else ignore call */
  547.     if (f == FALSE)
  548.         return(TRUE);
  549.  
  550.     /* find out what to do */
  551.     clines = curwp->w_ntrows;
  552.  
  553.     /* already the right size? */
  554.     if (clines == n)
  555.         return(TRUE);
  556.  
  557.     return(enlargewind(TRUE, n - clines));
  558. }
  559.  
  560. /*    pop up the indicated buffer
  561. */
  562.  
  563. #if    PROTO
  564. int PASCAL NEAR wpopup(BUFFER *popbuf)
  565. #else
  566. int PASCAL NEAR wpopup(popbuf)
  567.  
  568. BUFFER *popbuf;
  569. #endif
  570. {
  571.     register WINDOW *wp;
  572.     register BUFFER *bp;
  573.     register int cmark;        /* current mark */
  574.  
  575.     /* on screen already? */
  576.     if (popbuf->b_nwnd != 0)
  577.         goto setwin;
  578.  
  579.     /* if flaged so, do a real pop up */
  580.     if (popflag)
  581.         return(pop(popbuf));
  582.  
  583.     /* find the window to split */
  584.     if (wheadp->w_wndp == NULL        /* Only 1 window    */
  585.     && splitwind(FALSE, 0) == FALSE)    /* and it won't split    */
  586.         return(FALSE);
  587.     wp = wheadp;                /* Find window to use    */
  588.     while (wp!=NULL && wp == curwp)
  589.         wp = wp->w_wndp;
  590.  
  591.     if (popbuf->b_nwnd == 0) {        /* Not on screen yet.    */
  592.         bp = wp->w_bufp;
  593.         if (--bp->b_nwnd == 0) {
  594.             bp->b_dotp  = wp->w_dotp;
  595.             bp->b_doto  = wp->w_doto;
  596.             for (cmark = 0; cmark < NMARKS; cmark++) {
  597.                 bp->b_markp[cmark] = wp->w_markp[cmark];
  598.                 bp->b_marko[cmark] = wp->w_marko[cmark];
  599.             }
  600.             bp->b_fcol  = wp->w_fcol;
  601.         }
  602.         wp->w_bufp  = popbuf;
  603.         ++popbuf->b_nwnd;
  604.     }
  605.  
  606. setwin: wp = wheadp;
  607.     while (wp != NULL) {
  608.         if (wp->w_bufp == popbuf) {
  609.             wp->w_linep = lforw(popbuf->b_linep);
  610.             wp->w_dotp  = lforw(popbuf->b_linep);
  611.             wp->w_doto  = 0;
  612.             for (cmark = 0; cmark < NMARKS; cmark++) {
  613.                 wp->w_markp[cmark] = NULL;
  614.                 wp->w_marko[cmark] = 0;
  615.             }
  616.             wp->w_flag |= WFMODE|WFHARD;
  617.             popbuf->b_mode |= MDVIEW; /* put this buffer view mode */
  618.             upmode();
  619.         }
  620.         wp = wp->w_wndp;
  621.     }
  622.     return(TRUE);
  623. }
  624.  
  625. PASCAL NEAR nextup(f, n)    /* scroll the next window up (back) a page */
  626.  
  627. int f, n;    /* prefix flag and argument */
  628.  
  629. {
  630.     nextwind(FALSE, 1);
  631.     backpage(f, n);
  632.     prevwind(FALSE, 1);
  633.  
  634.     return (0);
  635. }
  636.  
  637. PASCAL NEAR nextdown(f, n)    /* scroll the next window down (forward) a page */
  638.  
  639. int f, n;    /* prefix flag and argument */
  640.  
  641. {
  642.     nextwind(FALSE, 1);
  643.     forwpage(f, n);
  644.     prevwind(FALSE, 1);
  645.  
  646.     return (0);
  647. }
  648.  
  649. PASCAL NEAR savewnd(f, n)    /* save ptr to current window */
  650.  
  651. int f, n;    /* prefix flag and argument */
  652.  
  653. {
  654.     swindow = curwp;
  655.     return(TRUE);
  656. }
  657.  
  658. PASCAL NEAR restwnd(f, n)    /* restore the saved screen */
  659.  
  660. int f, n;    /* prefix flag and argument */
  661.  
  662. {
  663.     register WINDOW *wp;
  664.  
  665.     /* find the window */
  666.     wp = wheadp;
  667.     while (wp != NULL) {
  668.         if (wp == swindow) {
  669.             curwp = wp;
  670.             curbp = wp->w_bufp;
  671.             upmode();
  672.             return (TRUE);
  673.         }
  674.         wp = wp->w_wndp;
  675.     }
  676.  
  677.     mlwrite(TEXT208);
  678. /*        "[No such window exists]" */
  679.     return(FALSE);
  680. }
  681.  
  682. PASCAL NEAR newsize(f, n)    /* resize the screen, re-writing the screen */
  683.  
  684. int f;    /* default flag */
  685. int n;    /* numeric argument */
  686.  
  687. {
  688.     WINDOW *wp;    /* current window being examined */
  689.     WINDOW *nextwp; /* next window to scan */
  690.     WINDOW *lastwp; /* last window scanned */
  691.     int lastline;    /* screen line of last line of current window */
  692.     int cmark;        /* current mark */
  693.  
  694.     /* if the command defaults, assume the largest */
  695.     if (f == FALSE)
  696.         n = term.t_mrow + 1;
  697.  
  698.     /* make sure it's in range */
  699.     if (n < 3 || n > term.t_mrow + 1) {
  700.         mlwrite(TEXT209);
  701. /*            "%%Screen size out of range" */
  702.         return(FALSE);
  703.     }
  704.  
  705.     if (term.t_nrow == n - 1)
  706.         return(TRUE);
  707.     else if (term.t_nrow < n - 1) {
  708.  
  709.         /* go to the last window */
  710.         wp = wheadp;
  711.         while (wp->w_wndp != NULL)
  712.             wp = wp->w_wndp;
  713.  
  714.         /* and enlarge it as needed */
  715.         wp->w_ntrows = n - wp->w_toprow - 2;
  716.         wp->w_flag |= WFHARD|WFMODE;
  717.  
  718.     } else {
  719.  
  720.         /* rebuild the window structure */
  721.         nextwp = wheadp;
  722.         wp = NULL;
  723.         lastwp = NULL;
  724.         while (nextwp != NULL) {
  725.             wp = nextwp;
  726.             nextwp = wp->w_wndp;
  727.         
  728.             /* get rid of it if it is too low */
  729.             if (wp->w_toprow > n - 2) {
  730.  
  731.                 /* save the point/mark if needed */
  732.                 if (--wp->w_bufp->b_nwnd == 0) {
  733.                     wp->w_bufp->b_dotp = wp->w_dotp;
  734.                     wp->w_bufp->b_doto = wp->w_doto;
  735.                     for (cmark = 0; cmark < NMARKS; cmark++) {
  736.                         wp->w_bufp->b_markp[cmark] = wp->w_markp[cmark];
  737.                         wp->w_bufp->b_marko[cmark] = wp->w_marko[cmark];
  738.                     }
  739.                     wp->w_bufp->b_fcol = wp->w_fcol;
  740.                 }
  741.         
  742.                 /* update curwp and lastwp if needed */
  743.                 if (wp == curwp)
  744.                     curwp = wheadp;
  745.                     curbp = curwp->w_bufp;
  746.                 if (lastwp != NULL)
  747.                     lastwp->w_wndp = NULL;
  748.  
  749.                 /* free the structure */
  750.                 free((char *)wp);
  751.                 wp = NULL;
  752.  
  753.             } else {
  754.                 /* need to change this window size? */
  755.                 lastline = wp->w_toprow + wp->w_ntrows - 1;
  756.                 if (lastline >= n - 2) {
  757.                     wp->w_ntrows = n - wp->w_toprow - 2;
  758.                     wp->w_flag |= WFHARD|WFMODE;
  759.                 }
  760.             }
  761.         
  762.             lastwp = wp;
  763.         }
  764.     }
  765.  
  766.     /* screen is garbage */
  767.     term.t_nrow = n - 1;
  768.     sgarbf = TRUE;
  769.     return(TRUE);
  770. }
  771.  
  772. PASCAL NEAR newwidth(f, n)    /* resize the screen, re-writing the screen */
  773.  
  774. int f;    /* default flag */
  775. int n;    /* numeric argument */
  776.  
  777. {
  778.     register WINDOW *wp;
  779.  
  780.     /* if the command defaults, assume the largest */
  781.     if (f == FALSE)
  782.         n = term.t_mcol;
  783.  
  784.     /* make sure it's in range */
  785.     if (n < 10 || n > term.t_mcol) {
  786.         mlwrite(TEXT210);
  787. /*            "%%Screen width out of range" */
  788.         return(FALSE);
  789.     }
  790.  
  791.     /* otherwise, just re-width it (no big deal) */
  792.     term.t_ncol = n;
  793.     term.t_margin = n / 10;
  794.     term.t_scrsiz = n - (term.t_margin * 2);
  795.  
  796.     /* force all windows to redraw */
  797.     wp = wheadp;
  798.     while (wp) {
  799.         wp->w_flag |= WFHARD | WFMOVE | WFMODE;
  800.         wp = wp->w_wndp;
  801.     }
  802.     sgarbf = TRUE;
  803.  
  804.     return(TRUE);
  805. }
  806.  
  807. PASCAL NEAR new_col_org(f, n)    /* reposition the screen, re-writing the screen */
  808.  
  809. int f;    /* default flag */
  810. int n;    /* numeric argument */
  811.  
  812. {
  813.     /* if the command defaults, assume zero */
  814.     if (f == FALSE)
  815.         n = 0;
  816.  
  817.     /* make sure it's in range */
  818.     if (n < 0 || n > term.t_mcol - term.t_ncol) {
  819.         mlwrite(TEXT223);
  820. /*            "%%Column origin out of range" */
  821.         return(FALSE);
  822.     }
  823.  
  824.     /* otherwise, just re-width it (no big deal) */
  825.     term.t_colorg = n;
  826.     sgarbf = TRUE;
  827.  
  828.     return(TRUE);
  829. }
  830.  
  831. PASCAL NEAR new_row_org(f, n)    /* reposition the screen, re-writing the screen */
  832.  
  833. int f;    /* default flag */
  834. int n;    /* numeric argument */
  835.  
  836. {
  837.     /* if the command defaults, assume zero */
  838.     if (f == FALSE)
  839.         n = 0;
  840.  
  841.     /* make sure it's in range */
  842.     if (n < 0 || n > term.t_mrow - term.t_nrow) {
  843.         mlwrite(TEXT224);
  844. /*            "%%Row origin out of range" */
  845.         return(FALSE);
  846.     }
  847.  
  848.     /* otherwise, just re-size it (no big deal) */
  849.     term.t_roworg = n;
  850.  
  851.     sgarbf = TRUE;
  852.     return(TRUE);
  853. }
  854.  
  855. int PASCAL NEAR getwpos()    /* get screen offset of current line in current window */
  856.  
  857. {
  858.     register int sline;    /* screen line from top of window */
  859.     register LINE *lp;    /* scannile line pointer */
  860.  
  861.     /* search down the line we want */
  862.     lp = curwp->w_linep;
  863.     sline = 1;
  864.     while (lp != curwp->w_dotp) {
  865.         ++sline;
  866.         lp = lforw(lp);
  867.     }
  868.  
  869.     /* and return the value */
  870.     return(sline);
  871. }
  872.  
  873. int PASCAL NEAR getcwnum()        /* get current window number */
  874.  
  875. {
  876.     register WINDOW *wp;
  877.     register int num;
  878.  
  879.     num = 1;
  880.     wp = wheadp;
  881.     while (wp != curwp) {
  882.         wp = wp->w_wndp;
  883.         num++;
  884.     }
  885.     return(num);
  886. }
  887.  
  888.  
  889. int PASCAL NEAR gettwnum()        /* get total window count */
  890.  
  891. {
  892.     register WINDOW *wp;
  893.     register int ctr;
  894.  
  895.     ctr = 0;
  896.     wp = wheadp;
  897.     while (wp) {
  898.         ctr++;
  899.         wp = wp->w_wndp;
  900.     }
  901.     return(ctr);
  902. }
  903.  
  904.